<?php
declare(strict_types=1);

namespace App\Controller;

use App\Helper\ApiHelper;
use App\Helper\RequestHelper;
use App\Model\ContentItem;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\ModelCache\Manager;
use Hyperf\Redis\Redis;
use Hyperf\Redis\RedisFactory;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Str;
use Hyperf\View\RenderInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * @Controller()
 */
class DetailController extends AbstractController
{
    /**
     * @GetMapping(path="/detail/{idWithPage}.html")
     * @param RenderInterface $render
     * @return ResponseInterface
     */
    public function index(RenderInterface $render): ResponseInterface
    {
        $idWithPage = trim($this->request->route('idWithPage', ''));
        if (empty($idWithPage)) { // 如果请求参数为空
            return $this->response->redirect('/404.html');
        }
        $idWithPage = explode('-', $idWithPage);
        if (count($idWithPage) > 2) { // 如果请求参数格式错误
            return $this->response->redirect('/404.html');
        }
        $id = intval($idWithPage[0] ?? 0);
        $page = intval($idWithPage[1] ?? 1);
        if ($id < 1 || $page < 1) { // 如果ID和页号错误
            return $this->response->redirect('/404.html');
        }
        /* @var Redis $redis */
        $redis = ApplicationContext::getContainer()->get(RedisFactory::class)->get('business');
        if (!$redis) { // 如果Redis连接失败
            return $this->response->redirect('/404.html');
        }
        $idRange = $redis->hGetAll('item_id_range');
        if (!$idRange) { // 如果Redis未查询到数据
            return $this->response->redirect('/404.html');
        }
        $idMin = $idRange['min'] ?? 0;
        $idMax = $idRange['max'] ?? 0;
        if ($id < $idMin || $id > $idMax) { // 如果ID不在有效范围
            return $this->response->redirect('/404.html');
        }
        $model = ContentItem::findFromCache($id);
        if (!$model
            || $model->main_id != 0
            || $model->type_id != 0
            || $model->status != 4
            || !empty($model->deleted_at)
        ) { // 如果不是有效的数据
            return $this->response->redirect('/404.html');
        }
        $queryBuilder = ContentItem::query()
            ->select(['id'])
            ->where('main_id', '=', $id)
            ->orderBy('page_number')
            ->orderBy('created_at');
        $ids = ContentItem::getIdsByBuilderFromCache($queryBuilder);
        if ($page == 1) { // 如果是第一页,用自身数据
            $detailItem = $model;
        } else {
            $detailId = intval($ids[$page - 2] ?? 0);
            if ($detailId <= 0) { // 如果分页的ID错误
                return $this->response->redirect('/404.html');
            }
            $detailItem = ContentItem::findFromCache($detailId);
            if (!$detailItem) { // 如果分页未查询到数据
                return $this->response->redirect('/404.html');
            }
        }
        if (!$detailItem->content_short) { // 简述为空,从内容中截取
            $detailItem->content_short = Str::substr(strip_tags($detailItem->content ?: ''), 0, 150);
        }
        return $render->render('item_detail.html', [
            'baseItem' => $model,
            'detailItem' => $detailItem,
            'pageCount' => 1 + count($ids),
            'id' => $id,
            'page' => $page,
        ]);
    }

    /**
     * @PostMapping(path="/detail/count.api")
     * @return ResponseInterface
     */
    public function viewOrLikeCount(): ResponseInterface
    {
        if (!RequestHelper::isAjax($this->request)) {
            return $this->response->redirect('/404.html');
        }
        $id = intval($this->request->post('id', 0));
        $type = trim($this->request->post('type', 'view'));
        if ($id < 1 || !in_array($type, ['view', 'like'], true)) {
            return $this->response->json(ApiHelper::genErrorData());
        }
        $model = ContentItem::findFromCache($id);
        if (!$model
            || $model->main_id != 0
            || $model->type_id != 0
            || $model->status != 4
            || !empty($model->deleted_at)
        ) {
            return $this->response->json(ApiHelper::genErrorData());
        }
        /* @var $redis Redis */
        $redis = ApplicationContext::getContainer()->get(RedisFactory::class)->get('business');
        if (!$redis) {
            return $this->response->json(ApiHelper::genErrorData());
        }
        if ($type == 'view') {
            $added = ApplicationContext::getContainer()->get(Manager::class)->increment($id, 'viewed_count', 1, ContentItem::class);
            $added && $redis->sAdd('item_viewed_or_liked', $id);
            return $this->response->json($added ? ApiHelper::genSuccessData() : ApiHelper::genErrorData());
        }
        if ($type == 'like') {
            $uid = RequestHelper::getGuestUid($this->request);
            if (!$uid) {
                return $this->response->json(ApiHelper::genErrorData('无法操作！'));
            }
            $liked = $redis->set('item_liked:' . $uid . ':' . $id, 1, ['nx', 'ex' => 86400]);
            if (!$liked) {
                return $this->response->json(ApiHelper::genErrorData('你已经点过赞了，谢谢。'));
            }
            $added = ApplicationContext::getContainer()->get(Manager::class)->increment($id, 'liked_count', 1, ContentItem::class);
            $added && $redis->sAdd('item_viewed_or_liked', $id);
            return $this->response->json($added ? ApiHelper::genSuccessData() : ApiHelper::genErrorData());
        }
        return $this->response->json(ApiHelper::genErrorData());
    }
}
